
/**
 * vue2的实现原理
 * Object.defineProperty只能劫持对象的属性，所以vue2中的响应式数据要存在data函数中
 */
const vue2 = (obj: any)=>{
    for(const key in obj){
        let value = obj[key]
        //判断是否是对像
        if(typeof value === 'object' && value !== null){
            vue2(value)
        }
        Object.defineProperty(obj, key, {
            get(){
                console.log('vue2 get',key)
                return value
            },
            set(val){
                console.log('vue2 set',val)
                if(val === value) return;
                value = val
            }
        })
    }
}   


/**
 * vue3 reactive的实现原理
 */
const reactive = (obj: any)=>{
    return new Proxy(obj,{
        get(target: any, key: string){
            if(typeof target[key] === 'object' && target[key] !== null){
                return reactive(target[key])
            }
            console.log('vue3 get', key, target[key])
            return target[key]
        },
        set(target: any, key: string, newVal: any){
            console.log('vue3 set', key, newVal)
            if(target[key] === newVal) return;
            return target[key] = newVal
        }
    });
}

/**
 * vue3的ref实现原理
 */
const vue3Ref = (obj: any)=>{
    const newObj = {value: obj}
    return reactive(newObj)
}

const runVue2 = ()=>{
    const data = {
        name:'zhangsan',
        obj:{
            name:'zhangsan'
        }
    }
    vue2(data)
    data.name = 'lisi'
    data.obj.name = 'lisi'
}
const runVue3 = ()=>{
    const data = {
        name:'zhangsan',
        obj:{
            name:'zhangsan'
        }
    }
    const proxyData = vue3Ref(data)
    proxyData.value.name
    proxyData.value.obj.name = 'lisi'
}

export {
    runVue2,
    runVue3
}